﻿package Leophy.controls.NumberSteps 
{
	import com.loomoo.ui.events.EventBlock;
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	import flash.utils.getTimer;
	
	/**
	 * ...
	 * @author TOPHY
	 */
	public class NumberStep extends EventDispatcher
	{
		
		////================================================= 事件
		public static var M_STEP:String = "onStep";
		
		
		////================================================= 变量
		/**
		 * 是否以整数形式跳动
		 */
		public var isIntValue:Boolean = true;
		/**
		 * 按下多少毫秒之后开始加速
		 */
		public var speedUpPreS:uint = 1000;
		
		private var _stopFrame:Number = 2;
		private var _stepStartTime:Number;
		private var _upNum:MovieClip;
		private var _downNum:MovieClip;
		private var _showTxt:TextField;
		
		private var _step:Number = 0.2;
		private var _value:Number = 0;
		private var _min:Number=0;
		private var _max:Number=100;
		
		////================================================= 属性
		/**
		 * 向上step的按钮UI
		 */
		public function get UpArrow():MovieClip {
			return _upNum;
		}
		public function set UpArrow(value:MovieClip):void {
			delUpArrowEvent();
			_upNum = value;
			addUpArrowEvent();
		}
		
		/**
		 * 向下step的按钮UI
		 */
		public function get DownArrow():MovieClip {
			return _downNum;
		}
		public function set DownArrow(value:MovieClip):void {
			delDownArrowEvent();
			_downNum = value;
			addDownArrowEvent();
		}
		
		/**
		 * 显示用的textfield
		 */
		public function get ShowText():TextField {
			return this._showTxt
		}
		public function set ShowText(value:TextField):void {
			this._showTxt = value;
		}
		
		/**
		 * 最大值
		 */
		public function get MaxValue():Number {
			return _max;
		}
		public function set MaxValue(value:Number):void {
			value = Math.max(_min, value);
			_max = value;
			
			if (_value > _max) {
				_value = _max;
				setValueToUI();
			}
		}
		/**
		 * 最小值
		 */
		public function get MinValue():Number {
			return _min;
		}
		public function set MinValue(value:Number):void {
			value = Math.min (_max, value);
			_min = value;
			
			if (_value < _min) {
				_value = _min;
				setValueToUI();
			}
		}
		/**
		 * 步进值
		 */
		public function get StepValue():Number {
			return _step;
		}
		public function set StepValue(value:Number):void {
			if (value <= 0) {
				trace("步进需要正值。");
				return;
			}
			
			_step = value;
		}
		/**
		 * 设置当前值
		 */
		public function get Value():Number {
			if(isIntValue){
				return Math.round(_value);
			}else {
				return _value;
			}
		}
		public function set Value(value:Number):void {
			value = Math.max(_min, value);
			value = Math.min(_max, value);
			if (_value != value) {
				_value = value;
				setValueToUI();
			}
		}
		////================================================= 函数
		public function NumberStep() 
		{
			
		}
		
		
		
		private function addUpArrowEvent():void {
			if (_upNum != null) {
				delUpArrowEvent();
			}
			_upNum.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownOnUpArrow);
		}
		private function delUpArrowEvent():void {
			if (_upNum != null) {
				_upNum.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDownOnUpArrow);
			}
		}
		
		private function mouseDownOnUpArrow(ev:MouseEvent):void {
			InitShowTextBeforStart();
			setSetpStartTime();
			if (_upNum.stage != null) {
				_upNum.stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpFun);
			}
			_upNum.addEventListener(MouseEvent.MOUSE_UP, mouseUpFun);
			_upNum.addEventListener(Event.ENTER_FRAME, upActionEnterFramefun);
		}
		
		
		private function addDownArrowEvent():void {
			if (_downNum != null) {
				delDownArrowEvent();
			}
			_downNum.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownOnDownArrow);
		}
		private function delDownArrowEvent():void {
			if (_downNum != null) {
				_downNum.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDownOnDownArrow);
			}
		}
		
		private function mouseDownOnDownArrow(ev:MouseEvent):void {
			InitShowTextBeforStart(false);
			setSetpStartTime();
			if (_downNum.stage != null) {
				_downNum.stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpFun);
			}
			_downNum.addEventListener(MouseEvent.MOUSE_UP, mouseUpFun);
			_downNum.addEventListener(Event.ENTER_FRAME, downActionEnterFramefun);
		}
		
		
		private function upActionEnterFramefun(ev:Event):void {
			if (_stopFrame-->0) return;
			if (_value >= _max) {
				mouseUpFun();
			}
			var byn:Number = int((getTimer() - _stepStartTime) / speedUpPreS)+1;
			_value += _step*byn;
			_value = Math.min(_max, _value);
			setValueToUI();
		}
		private function downActionEnterFramefun(ev:Event):void {
			if (_stopFrame-->0) return;
			if (_value <= _min) {
				mouseUpFun();
			}
			var byn:Number = int((getTimer() - _stepStartTime) / speedUpPreS)+1;
			_value -= _step*byn;
			_value = Math.max(_min, _value);
			setValueToUI();
		}
		private function mouseUpFun(ev:MouseEvent=null):void {
			_downNum.removeEventListener(Event.ENTER_FRAME, downActionEnterFramefun);
			_upNum.removeEventListener(Event.ENTER_FRAME, upActionEnterFramefun);
			if (_upNum.stage != null) {
				_upNum.stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpFun);
			}
			if (_downNum.stage != null) {
				_downNum.stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpFun);
			}
		}
		
		private function InitShowTextBeforStart(isUp:Boolean=true) {
			if (_showTxt != null) {
				if (Number(_showTxt.text).toString() == "NaN") {
					_value = _min;
				}else {
					Value = Number(_showTxt.text)+(((isUp)? 1:-1)*((isIntValue)? 1:_step));
				}
			}
		}
		
		private function setSetpStartTime() {
			_stepStartTime = getTimer();
			_stopFrame = 2;
		}
		
		private function setValueToUI():void {
			if (this._showTxt != null) {
				this._showTxt.text = Math.round(_value).toString();
			}
			this.dispatchEvent(new Event(M_STEP));
		}
		
	}
	
}